using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityStandardAssets.CrossPlatformInput;

namespace VoxelEngine.Events
{
	public class VoxelInputEvents : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IEventSystemHandler
	{
		public enum LongPressState
		{
			Begin,
			Hold,
			Detected,
			Failed,
			End
		}

		private enum DetectionState
		{
			UnknowBegin,
			LongPressCandidate,
			TapDetected,
			LongPressDetected,
			Failed,
			None
		}

		[SerializeField]
		private float _maxTapInterval = 0.2f;

		[SerializeField]
		private float _maxTapDragDelta = 0.1f;

		[SerializeField]
		private float _longPressStartDelay = 1f;

		[SerializeField]
		private float _sensitivity = 1f;

		[SerializeField]
		private float _referenceWidth = 1920f;

		private int _pointerId;

		private float _startTime;

		private Vector2 _startPosition;

		private bool _longPressFailed;

		private bool _isLongPressing;

		private bool _isFirstLongPress;

		private float _aspectSensitivity;

		private Vector2 _previousTouchPos;

		private Vector3 _center;

		private Graphic _image;

		private CrossPlatformInputManager.VirtualAxis _horizontalVirtualAxis;

		private CrossPlatformInputManager.VirtualAxis _verticalVirtualAxis;

		public string horizontalAxisName = "Horizontal";

		public string verticalAxisName = "Vertical";

		private DetectionState _detectionState = DetectionState.None;

		public event Action<LongPressState, Vector2> OnLongPress;

		public event Action<float> OnLongPressProgress;

		public event Action<Vector2> OnTap;

		public event Action<Vector2> OnDragEvent;

		private void Start()
		{
			_maxTapDragDelta = (float)Screen.width * _maxTapDragDelta;
			_image = GetComponent<Graphic>();
			_center = _image.transform.position;
			_aspectSensitivity = _referenceWidth / (float)Screen.width;
		}

		private void OnEnable()
		{
			CreateVirtualAxes();
		}

		private void OnDisable()
		{
			CrossPlatformInputManager.UnRegisterVirtualAxis(horizontalAxisName);
			CrossPlatformInputManager.UnRegisterVirtualAxis(verticalAxisName);
		}

		private void CreateVirtualAxes()
		{
			_horizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
			CrossPlatformInputManager.RegisterVirtualAxis(_horizontalVirtualAxis);
			_verticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
			CrossPlatformInputManager.RegisterVirtualAxis(_verticalVirtualAxis);
		}

		private void UpdateVirtualAxes(Vector3 value)
		{
			_horizontalVirtualAxis.Update(value.x);
			_verticalVirtualAxis.Update(value.y);
		}

		private void Update()
		{
			if (_detectionState == DetectionState.None)
			{
				return;
			}
			Vector2 vector = Vector2.zero;
			if (UnityEngine.Input.touchCount < _pointerId + 1 || _pointerId == -1)
			{
				return;
			}
			Vector2 position = Input.touches[_pointerId].position;
			float x = position.x;
			Vector2 position2 = Input.touches[_pointerId].position;
			vector = new Vector2(x, position2.y);
			if (this.OnDragEvent != null)
			{
				this.OnDragEvent(vector);
			}
			if (_detectionState != DetectionState.Failed)
			{
				float distance = Vector2.Distance(vector, _startPosition);
				if (ValidateMaxDrag(distance) || _detectionState == DetectionState.LongPressDetected)
				{
					float num = Time.time - _startTime;
					this.OnLongPressProgress.Fire(Mathf.Lerp(0f, 1f, num / _longPressStartDelay));
					if (_detectionState == DetectionState.LongPressCandidate || _detectionState == DetectionState.LongPressDetected)
					{
						if (num >= _longPressStartDelay)
						{
							_detectionState = DetectionState.LongPressDetected;
							_isFirstLongPress = false;
							this.OnLongPress.Fire(LongPressState.Hold, vector);
						}
					}
					else if (_detectionState == DetectionState.UnknowBegin && num > _maxTapInterval)
					{
						_detectionState = DetectionState.LongPressCandidate;
						this.OnLongPress.Fire(LongPressState.Detected, vector);
					}
				}
				else
				{
					_detectionState = DetectionState.Failed;
					this.OnLongPress.Fire(LongPressState.Failed, vector);
				}
			}
			_center = _previousTouchPos;
			_previousTouchPos = vector;
			Vector2 vector2 = new Vector2((vector.x - _center.x) * _aspectSensitivity, (vector.y - _center.y) * _aspectSensitivity);
			vector2.x *= _sensitivity;
			vector2.y *= _sensitivity;
			UpdateVirtualAxes(new Vector3(vector2.x, vector2.y, 0f));
		}

		private bool ValidateMaxDrag(float distance)
		{
			float num = (!_isFirstLongPress) ? (_maxTapDragDelta * 2f) : _maxTapDragDelta;
			return distance <= num;
		}

		public void OnPointerDown(PointerEventData data)
		{
			if (_detectionState == DetectionState.None)
			{
				_detectionState = DetectionState.UnknowBegin;
				_pointerId = data.pointerId;
				_startTime = Time.time;
				_startPosition = data.position;
				_previousTouchPos = data.position;
				_isFirstLongPress = true;
				this.OnLongPress.Fire(LongPressState.Begin, _startPosition);
			}
		}

		public void OnPointerUp(PointerEventData data)
		{
			if (data.pointerId == _pointerId)
			{
				UpdateVirtualAxes(Vector3.zero);
				if (_detectionState == DetectionState.UnknowBegin)
				{
					this.OnTap(_startPosition);
					this.OnLongPress.Fire(LongPressState.Failed, data.position);
				}
				this.OnLongPress.Fire(LongPressState.End, data.position);
			}
			_detectionState = DetectionState.None;
		}
	}
}
